/*!
 * \file test_file_io_comprehensive.cpp
 * \project WonderTrader
 *
 * \author AI Assistant
 * \date 2024/12/01
 * 
 * \brief 文件I/O工具类的综合测试文件
 * 
 * \details 本文件包含对文件输入输出工具类的全面测试，涵盖：
 *          - 文件读写基本操作
 *          - 二进制文件处理
 *          - CSV文件解析和生成
 *          - 配置文件处理
 *          - 文件系统操作和路径处理
 *          - 错误处理和异常情况测试
 */

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <filesystem>
#include <chrono>
#include <thread>
#include <atomic>

// 模拟文件I/O工具类
namespace {

/*!
 * \brief 文件I/O工具类
 * \details 提供常用的文件操作功能
 */
class FileIOUtils {
public:
    /*!
     * \brief 读取文本文件内容
     * \param filename 文件名
     * \return 文件内容字符串
     */
    static std::string readTextFile(const std::string& filename) {
        std::ifstream file(filename);
        if (!file.is_open()) {
            return "";
        }
        
        std::stringstream buffer;
        buffer << file.rdbuf();
        return buffer.str();
    }
    
    /*!
     * \brief 写入文本文件
     * \param filename 文件名
     * \param content 文件内容
     * \return 是否成功
     */
    static bool writeTextFile(const std::string& filename, const std::string& content) {
        std::ofstream file(filename);
        if (!file.is_open()) {
            return false;
        }
        
        file << content;
        return file.good();
    }
    
    /*!
     * \brief 追加内容到文件
     * \param filename 文件名
     * \param content 追加内容
     * \return 是否成功
     */
    static bool appendToFile(const std::string& filename, const std::string& content) {
        std::ofstream file(filename, std::ios::app);
        if (!file.is_open()) {
            return false;
        }
        
        file << content;
        return file.good();
    }
    
    /*!
     * \brief 读取文件所有行
     * \param filename 文件名
     * \return 行内容向量
     */
    static std::vector<std::string> readLines(const std::string& filename) {
        std::vector<std::string> lines;
        std::ifstream file(filename);
        
        if (!file.is_open()) {
            return lines;
        }
        
        std::string line;
        while (std::getline(file, line)) {
            lines.push_back(line);
        }
        
        return lines;
    }
    
    /*!
     * \brief 写入多行到文件
     * \param filename 文件名
     * \param lines 行内容向量
     * \return 是否成功
     */
    static bool writeLines(const std::string& filename, const std::vector<std::string>& lines) {
        std::ofstream file(filename);
        if (!file.is_open()) {
            return false;
        }
        
        for (const auto& line : lines) {
            file << line << std::endl;
        }
        
        return file.good();
    }
    
    /*!
     * \brief 解析CSV文件
     * \param filename 文件名
     * \param delimiter 分隔符
     * \return CSV数据（行列二维向量）
     */
    static std::vector<std::vector<std::string>> parseCSV(const std::string& filename, char delimiter = ',') {
        std::vector<std::vector<std::string>> result;
        std::ifstream file(filename);
        
        if (!file.is_open()) {
            return result;
        }
        
        std::string line;
        while (std::getline(file, line)) {
            std::vector<std::string> row;
            std::stringstream ss(line);
            std::string cell;
            
            while (std::getline(ss, cell, delimiter)) {
                row.push_back(cell);
            }
            
            if (!row.empty()) {
                result.push_back(row);
            }
        }
        
        return result;
    }
    
    /*!
     * \brief 写入CSV文件
     * \param filename 文件名
     * \param data CSV数据
     * \param delimiter 分隔符
     * \return 是否成功
     */
    static bool writeCSV(const std::string& filename, 
                        const std::vector<std::vector<std::string>>& data, 
                        char delimiter = ',') {
        std::ofstream file(filename);
        if (!file.is_open()) {
            return false;
        }
        
        for (const auto& row : data) {
            for (size_t i = 0; i < row.size(); ++i) {
                file << row[i];
                if (i < row.size() - 1) {
                    file << delimiter;
                }
            }
            file << std::endl;
        }
        
        return file.good();
    }
    
    /*!
     * \brief 检查文件是否存在
     * \param filename 文件名
     * \return 是否存在
     */
    static bool fileExists(const std::string& filename) {
        std::ifstream file(filename);
        return file.good();
    }
    
    /*!
     * \brief 获取文件大小
     * \param filename 文件名
     * \return 文件大小（字节）
     */
    static size_t getFileSize(const std::string& filename) {
        std::ifstream file(filename, std::ios::binary | std::ios::ate);
        if (!file.is_open()) {
            return 0;
        }
        return static_cast<size_t>(file.tellg());
    }
    
    /*!
     * \brief 删除文件
     * \param filename 文件名
     * \return 是否成功
     */
    static bool deleteFile(const std::string& filename) {
        return std::remove(filename.c_str()) == 0;
    }
    
    /*!
     * \brief 复制文件
     * \param source 源文件
     * \param destination 目标文件
     * \return 是否成功
     */
    static bool copyFile(const std::string& source, const std::string& destination) {
        std::ifstream src(source, std::ios::binary);
        std::ofstream dst(destination, std::ios::binary);
        
        if (!src.is_open() || !dst.is_open()) {
            return false;
        }
        
        dst << src.rdbuf();
        return src.good() && dst.good();
    }
    
    /*!
     * \brief 创建目录
     * \param path 目录路径
     * \return 是否成功
     */
    static bool createDirectory(const std::string& path) {
        try {
            return std::filesystem::create_directories(path);
        } catch (...) {
            return false;
        }
    }
    
    /*!
     * \brief 获取文件扩展名
     * \param filename 文件名
     * \return 扩展名
     */
    static std::string getFileExtension(const std::string& filename) {
        size_t pos = filename.find_last_of('.');
        if (pos == std::string::npos) {
            return "";
        }
        return filename.substr(pos + 1);
    }
    
    /*!
     * \brief 获取文件名（不含路径）
     * \param filepath 文件路径
     * \return 文件名
     */
    static std::string getFileName(const std::string& filepath) {
        size_t pos = filepath.find_last_of("/\\");
        if (pos == std::string::npos) {
            return filepath;
        }
        return filepath.substr(pos + 1);
    }
};

} // anonymous namespace

/*!
 * \brief 文件I/O工具类测试套件
 */
class FileIOUtilsTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 创建测试目录
        test_dir = "test_files";
        FileIOUtils::createDirectory(test_dir);
        
        // 准备测试文件名
        test_file = test_dir + "/test.txt";
        test_csv_file = test_dir + "/test.csv";
        test_binary_file = test_dir + "/test.bin";
    }
    
    void TearDown() override {
        // 清理测试文件
        FileIOUtils::deleteFile(test_file);
        FileIOUtils::deleteFile(test_csv_file);
        FileIOUtils::deleteFile(test_binary_file);
        
        // 删除测试目录
        try {
            std::filesystem::remove_all(test_dir);
        } catch (...) {
            // 忽略删除错误
        }
    }
    
    std::string test_dir;
    std::string test_file;
    std::string test_csv_file;
    std::string test_binary_file;
};

/*!
 * \brief 测试基本文件读写功能
 */
TEST_F(FileIOUtilsTest, TestBasicFileOperations) {
    // 测试写入文件
    std::string test_content = "Hello, World!\nThis is a test file.";
    EXPECT_TRUE(FileIOUtils::writeTextFile(test_file, test_content));
    
    // 测试文件是否存在
    EXPECT_TRUE(FileIOUtils::fileExists(test_file));
    
    // 测试读取文件
    std::string read_content = FileIOUtils::readTextFile(test_file);
    EXPECT_EQ(read_content, test_content);
    
    // 测试获取文件大小
    size_t file_size = FileIOUtils::getFileSize(test_file);
    EXPECT_EQ(file_size, test_content.length());
    
    std::cout << "基本文件读写测试通过" << std::endl;
}

/*!
 * \brief 测试文件追加功能
 */
TEST_F(FileIOUtilsTest, TestFileAppend) {
    // 写入初始内容
    std::string initial_content = "Line 1\n";
    EXPECT_TRUE(FileIOUtils::writeTextFile(test_file, initial_content));
    
    // 追加内容
    std::string append_content = "Line 2\nLine 3\n";
    EXPECT_TRUE(FileIOUtils::appendToFile(test_file, append_content));
    
    // 验证最终内容
    std::string final_content = FileIOUtils::readTextFile(test_file);
    EXPECT_EQ(final_content, initial_content + append_content);
    
    std::cout << "文件追加功能测试通过" << std::endl;
}

/*!
 * \brief 测试按行读写功能
 */
TEST_F(FileIOUtilsTest, TestLineOperations) {
    // 准备测试行数据
    std::vector<std::string> test_lines = {
        "第一行内容",
        "第二行内容",
        "第三行内容",
        "包含特殊字符的行: !@#$%^&*()"
    };
    
    // 写入行数据
    EXPECT_TRUE(FileIOUtils::writeLines(test_file, test_lines));
    
    // 读取行数据
    auto read_lines = FileIOUtils::readLines(test_file);
    ASSERT_EQ(read_lines.size(), test_lines.size());
    
    for (size_t i = 0; i < test_lines.size(); ++i) {
        EXPECT_EQ(read_lines[i], test_lines[i]);
    }
    
    std::cout << "按行读写功能测试通过" << std::endl;
}

/*!
 * \brief 测试CSV文件处理
 */
TEST_F(FileIOUtilsTest, TestCSVOperations) {
    // 准备CSV测试数据
    std::vector<std::vector<std::string>> csv_data = {
        {"Name", "Age", "City"},
        {"张三", "25", "北京"},
        {"李四", "30", "上海"},
        {"王五", "28", "深圳"}
    };
    
    // 写入CSV文件
    EXPECT_TRUE(FileIOUtils::writeCSV(test_csv_file, csv_data));
    
    // 读取CSV文件
    auto read_csv_data = FileIOUtils::parseCSV(test_csv_file);
    ASSERT_EQ(read_csv_data.size(), csv_data.size());
    
    for (size_t i = 0; i < csv_data.size(); ++i) {
        ASSERT_EQ(read_csv_data[i].size(), csv_data[i].size());
        for (size_t j = 0; j < csv_data[i].size(); ++j) {
            EXPECT_EQ(read_csv_data[i][j], csv_data[i][j]);
        }
    }
    
    // 测试不同分隔符
    std::string pipe_csv_file = test_dir + "/test_pipe.csv";
    EXPECT_TRUE(FileIOUtils::writeCSV(pipe_csv_file, csv_data, '|'));
    auto pipe_data = FileIOUtils::parseCSV(pipe_csv_file, '|');
    EXPECT_EQ(pipe_data.size(), csv_data.size());
    
    FileIOUtils::deleteFile(pipe_csv_file);
    std::cout << "CSV文件处理测试通过" << std::endl;
}

/*!
 * \brief 测试文件复制功能
 */
TEST_F(FileIOUtilsTest, TestFileCopy) {
    // 创建源文件
    std::string source_content = "这是要复制的文件内容\n包含中文字符";
    EXPECT_TRUE(FileIOUtils::writeTextFile(test_file, source_content));
    
    // 复制文件
    std::string copy_file = test_dir + "/copy.txt";
    EXPECT_TRUE(FileIOUtils::copyFile(test_file, copy_file));
    
    // 验证复制结果
    EXPECT_TRUE(FileIOUtils::fileExists(copy_file));
    std::string copy_content = FileIOUtils::readTextFile(copy_file);
    EXPECT_EQ(copy_content, source_content);
    
    // 验证文件大小
    EXPECT_EQ(FileIOUtils::getFileSize(test_file), FileIOUtils::getFileSize(copy_file));
    
    // 清理复制的文件
    FileIOUtils::deleteFile(copy_file);
    std::cout << "文件复制功能测试通过" << std::endl;
}

/*!
 * \brief 测试路径和文件名处理
 */
TEST_F(FileIOUtilsTest, TestPathOperations) {
    // 测试获取文件扩展名
    EXPECT_EQ(FileIOUtils::getFileExtension("test.txt"), "txt");
    EXPECT_EQ(FileIOUtils::getFileExtension("data.csv"), "csv");
    EXPECT_EQ(FileIOUtils::getFileExtension("noextension"), "");
    EXPECT_EQ(FileIOUtils::getFileExtension("file.tar.gz"), "gz");
    
    // 测试获取文件名
    EXPECT_EQ(FileIOUtils::getFileName("/path/to/file.txt"), "file.txt");
    EXPECT_EQ(FileIOUtils::getFileName("C:\\Windows\\file.exe"), "file.exe");
    EXPECT_EQ(FileIOUtils::getFileName("filename.txt"), "filename.txt");
    EXPECT_EQ(FileIOUtils::getFileName("/path/to/dir/"), "");
    
    std::cout << "路径和文件名处理测试通过" << std::endl;
}

/*!
 * \brief 测试错误处理
 */
TEST_F(FileIOUtilsTest, TestErrorHandling) {
    // 测试读取不存在的文件
    std::string non_existent = "non_existent_file.txt";
    EXPECT_FALSE(FileIOUtils::fileExists(non_existent));
    EXPECT_EQ(FileIOUtils::readTextFile(non_existent), "");
    EXPECT_EQ(FileIOUtils::getFileSize(non_existent), 0);
    
    // 测试读取空文件
    std::string empty_file = test_dir + "/empty.txt";
    EXPECT_TRUE(FileIOUtils::writeTextFile(empty_file, ""));
    EXPECT_TRUE(FileIOUtils::fileExists(empty_file));
    EXPECT_EQ(FileIOUtils::getFileSize(empty_file), 0);
    EXPECT_EQ(FileIOUtils::readTextFile(empty_file), "");
    
    // 测试写入到无效路径
    std::string invalid_path = "/invalid/path/file.txt";
    EXPECT_FALSE(FileIOUtils::writeTextFile(invalid_path, "content"));
    
    // 清理
    FileIOUtils::deleteFile(empty_file);
    std::cout << "错误处理测试通过" << std::endl;
}

/*!
 * \brief 测试大文件处理
 */
TEST_F(FileIOUtilsTest, TestLargeFileHandling) {
    // 创建较大的测试内容
    std::string large_content;
    large_content.reserve(100000);
    
    for (int i = 0; i < 10000; ++i) {
        large_content += "这是第" + std::to_string(i) + "行内容\n";
    }
    
    auto start_time = std::chrono::high_resolution_clock::now();
    
    // 写入大文件
    EXPECT_TRUE(FileIOUtils::writeTextFile(test_file, large_content));
    
    // 读取大文件
    std::string read_content = FileIOUtils::readTextFile(test_file);
    
    auto end_time = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time);
    
    // 验证内容正确性
    EXPECT_EQ(read_content, large_content);
    EXPECT_EQ(FileIOUtils::getFileSize(test_file), large_content.length());
    
    std::cout << "大文件处理测试通过，文件大小: " << large_content.length() 
              << " 字节，耗时: " << duration.count() << "ms" << std::endl;
    
    // 性能应该在合理范围内
    EXPECT_LT(duration.count(), 5000);  // 应该在5秒内完成
}

/*!
 * \brief 测试并发文件操作
 */
TEST_F(FileIOUtilsTest, TestConcurrentFileOperations) {
    const int num_threads = 4;
    const int files_per_thread = 10;
    std::atomic<int> success_count{0};
    
    std::vector<std::thread> threads;
    
    for (int t = 0; t < num_threads; ++t) {
        threads.emplace_back([&, t]() {
            for (int i = 0; i < files_per_thread; ++i) {
                std::string thread_file = test_dir + "/thread_" + std::to_string(t) + "_" + std::to_string(i) + ".txt";
                std::string content = "Thread " + std::to_string(t) + " File " + std::to_string(i);
                
                // 写入文件
                if (FileIOUtils::writeTextFile(thread_file, content)) {
                    // 读取文件验证
                    std::string read_content = FileIOUtils::readTextFile(thread_file);
                    if (read_content == content) {
                        success_count++;
                    }
                    
                    // 清理文件
                    FileIOUtils::deleteFile(thread_file);
                }
            }
        });
    }
    
    for (auto& thread : threads) {
        thread.join();
    }
    
    EXPECT_EQ(success_count.load(), num_threads * files_per_thread);
    std::cout << "并发文件操作测试通过，成功操作: " << success_count.load() << " 个文件" << std::endl;
}

/*!
 * \brief 测试特殊字符处理
 */
TEST_F(FileIOUtilsTest, TestSpecialCharacterHandling) {
    // 测试各种特殊字符
    std::string special_content = "特殊字符测试:\n";
    special_content += "中文字符: 你好世界\n";
    special_content += "英文字符: Hello World\n";
    special_content += "数字: 1234567890\n";
    special_content += "符号: !@#$%^&*()_+-=[]{}|;':\",./<>?\n";
    special_content += "制表符:\t制表符\n";
    special_content += "换行符测试\r\n";
    special_content += "Unicode: 🌍🚀💻📊\n";
    
    // 写入和读取
    EXPECT_TRUE(FileIOUtils::writeTextFile(test_file, special_content));
    std::string read_content = FileIOUtils::readTextFile(test_file);
    
    // 验证内容（注意：某些特殊字符可能在文件系统中有不同表现）
    EXPECT_FALSE(read_content.empty());
    EXPECT_GT(read_content.length(), 50);  // 应该有合理的长度
    
    std::cout << "特殊字符处理测试通过" << std::endl;
}

/*!
 * \brief 测试配置文件处理
 */
TEST_F(FileIOUtilsTest, TestConfigFileHandling) {
    // 创建模拟配置文件内容
    std::vector<std::string> config_lines = {
        "# 配置文件示例",
        "[database]",
        "host=localhost",
        "port=3306",
        "username=admin",
        "password=secret",
        "",
        "[logging]",
        "level=INFO",
        "file=/var/log/app.log",
        "",
        "# 注释行",
        "[features]",
        "enable_cache=true",
        "max_connections=100"
    };
    
    // 写入配置文件
    std::string config_file = test_dir + "/config.ini";
    EXPECT_TRUE(FileIOUtils::writeLines(config_file, config_lines));
    
    // 读取配置文件
    auto read_config = FileIOUtils::readLines(config_file);
    EXPECT_EQ(read_config.size(), config_lines.size());
    
    // 验证关键配置项
    bool found_host = false;
    bool found_port = false;
    bool found_level = false;
    
    for (const auto& line : read_config) {
        if (line.find("host=localhost") != std::string::npos) found_host = true;
        if (line.find("port=3306") != std::string::npos) found_port = true;
        if (line.find("level=INFO") != std::string::npos) found_level = true;
    }
    
    EXPECT_TRUE(found_host);
    EXPECT_TRUE(found_port);
    EXPECT_TRUE(found_level);
    
    // 清理
    FileIOUtils::deleteFile(config_file);
    std::cout << "配置文件处理测试通过" << std::endl;
}

/*!
 * \brief 测试完整的文件处理工作流程
 */
TEST_F(FileIOUtilsTest, TestCompleteFileWorkflow) {
    // 第一步：创建原始数据文件
    std::vector<std::vector<std::string>> original_data = {
        {"日期", "开盘价", "最高价", "最低价", "收盘价", "成交量"},
        {"2024-01-01", "100.00", "105.00", "99.00", "103.50", "1000000"},
        {"2024-01-02", "103.50", "108.00", "102.00", "106.25", "1200000"},
        {"2024-01-03", "106.25", "107.50", "104.00", "105.75", "950000"}
    };
    
    std::string data_file = test_dir + "/market_data.csv";
    EXPECT_TRUE(FileIOUtils::writeCSV(data_file, original_data));
    
    // 第二步：读取并处理数据
    auto read_data = FileIOUtils::parseCSV(data_file);
    ASSERT_EQ(read_data.size(), original_data.size());
    
    // 第三步：数据转换和分析
    std::vector<std::string> analysis_lines;
    analysis_lines.push_back("# 市场数据分析报告");
    analysis_lines.push_back("生成时间: 2024-12-01");
    analysis_lines.push_back("");
    
    double total_volume = 0.0;
    for (size_t i = 1; i < read_data.size(); ++i) {  // 跳过标题行
        if (read_data[i].size() >= 6) {
            double volume = std::stod(read_data[i][5]);
            total_volume += volume;
            
            std::string line = "日期: " + read_data[i][0] + 
                              ", 收盘价: " + read_data[i][4] + 
                              ", 成交量: " + read_data[i][5];
            analysis_lines.push_back(line);
        }
    }
    
    analysis_lines.push_back("");
    analysis_lines.push_back("总成交量: " + std::to_string(static_cast<long long>(total_volume)));
    analysis_lines.push_back("平均成交量: " + std::to_string(static_cast<long long>(total_volume / 3)));
    
    // 第四步：生成分析报告
    std::string report_file = test_dir + "/analysis_report.txt";
    EXPECT_TRUE(FileIOUtils::writeLines(report_file, analysis_lines));
    
    // 第五步：创建备份
    std::string backup_file = test_dir + "/market_data_backup.csv";
    EXPECT_TRUE(FileIOUtils::copyFile(data_file, backup_file));
    
    // 第六步：验证所有文件
    EXPECT_TRUE(FileIOUtils::fileExists(data_file));
    EXPECT_TRUE(FileIOUtils::fileExists(report_file));
    EXPECT_TRUE(FileIOUtils::fileExists(backup_file));
    
    // 验证文件大小
    EXPECT_GT(FileIOUtils::getFileSize(data_file), 0);
    EXPECT_GT(FileIOUtils::getFileSize(report_file), 0);
    EXPECT_EQ(FileIOUtils::getFileSize(data_file), FileIOUtils::getFileSize(backup_file));
    
    // 第七步：清理临时文件
    FileIOUtils::deleteFile(data_file);
    FileIOUtils::deleteFile(report_file);
    FileIOUtils::deleteFile(backup_file);
    
    std::cout << "完整文件处理工作流程测试通过" << std::endl;
    std::cout << "处理了 " << (original_data.size() - 1) << " 条市场数据记录" << std::endl;
    std::cout << "总成交量: " << static_cast<long long>(total_volume) << std::endl;
} 